﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using Barbar.Colonization.Core.Localization;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;

namespace Barbar.Colonization.Model.RuleSets {
  [XmlType(Namespace = Constants.XmlRootNamespace, TypeName = "TileType")]
  public class XmlTileType : XmlEntity, ITileType, IRulesetDeserialization {
    private string m_NameCode;
    private string m_DescriptionCode;
    private XmlTerrainTypeRef m_TerrainTypeRef;
    private int m_MoveCost;
    private int m_DefenseBonus;
    private XmlBonusResourceTypeRef m_BonusResourceTypeRef;
    private Collection<XmlTileProduction> m_XmlTileProductions = new Collection<XmlTileProduction>();
    private ReadOnlyCollection<ITileProduction> m_TileProductions;
    private XmlImageStack m_XmlImageStack;

    private TranslatorString m_Name;
    private TranslatorString m_Description;
    private ITerrainType m_TerrainType;

    public string NameCode {
      get { return m_NameCode; }
      set { m_NameCode = value; }
    }

    public string DescriptionCode {
      get { return m_DescriptionCode; }
      set { m_DescriptionCode = value; }
    }

    public XmlTerrainTypeRef TerrainTypeRef {
      get { return m_TerrainTypeRef; }
      set { m_TerrainTypeRef = value; }
    }

    public int MoveCost {
      get { return m_MoveCost; }
      set { m_MoveCost = value; }
    }

    public int DefenseBonus {
      get { return m_DefenseBonus; }
      set { m_DefenseBonus = value; }
    }

    [XmlArray(ElementName="Images")]
    public XmlImageStack ImageStack {
      get { return m_XmlImageStack; }
      set { m_XmlImageStack = value; }
    }

    public Collection<XmlTileProduction> TileProductions {
      get { return m_XmlTileProductions; }
    }

    public XmlBonusResourceTypeRef BonusResourceTypeRef {
      get { return m_BonusResourceTypeRef; }
      set { m_BonusResourceTypeRef = value; }
    }

    public override string ToString() {
      if (m_Name != null)
        return m_Name.ToString();
      return m_NameCode;
    }

    #region ITileType Members

    TranslatorString ITileType.Name {
      get { return m_Name; }
    }

    TranslatorString ITileType.Description {
      get { return m_Description; }
    }

    ITerrainType ITileType.TerrainType {
      get { return m_TerrainType; }
    }

    int ITileType.MoveCost {
      get { return m_MoveCost; }
    }

    int ITileType.DefenseBonus {
      get { return m_DefenseBonus; }
    }

    ReadOnlyCollection<ITileProduction> ITileType.TileProductions {
      get { return m_TileProductions; }
    }

    IImageStack ITileType.Images {
      get {return m_XmlImageStack; }
    }

    Tile ITileType.CreateEmptyTile(Coordinate coordinate) {
      return new Tile(coordinate, this);
    }

    #endregion

    #region IRulesetDeserialization Members

    void IRulesetDeserialization.OnDeserialization(XmlRuleSet ruleSet) {
      if (ruleSet == null)
        throw new ArgumentNullException("ruleSet");

      m_Name = new TranslatorString(m_NameCode);
      m_Description = new TranslatorString(m_DescriptionCode);

      foreach (XmlTerrainType terrainType in ruleSet.TerrainTypes) {
        if (terrainType.Id == m_TerrainTypeRef.IdRef) {
          m_TerrainType = (ITerrainType)terrainType;
          break;
        }
      }

      Collection<ITileProduction> tileProductions = new Collection<ITileProduction>();
      foreach(XmlTileProduction tileProduction in m_XmlTileProductions) {
        ((IRulesetDeserialization)tileProduction).OnDeserialization(ruleSet);
        tileProductions.Add(tileProduction);
      }
      m_TileProductions = new ReadOnlyCollection<ITileProduction>(tileProductions);

      ((IRulesetDeserialization)m_XmlImageStack).OnDeserialization(ruleSet);
    }

    #endregion
  }
}
